/*
 * WendySimple.c
 *
 * Updated: 12/24/2014 2:20 PM
 * Author: Matthew & Friends
 */ 

#define __AVR_ATtiny44A__ //Microprocessor Selection
#define F_CPU 2000000UL //2MHz Unsigned Long

#define __OPTIMIZE__ true

#define bool char
#define true 1
#define false !true

bool motorRunning = false;
bool displayLEDs = false;

volatile long myTimeMs = 0;
volatile int Vbatt = 0;

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

// Set Register Bits
inline void setBit8(char value, char bit){
	value |= (1 << bit);
}

// Clear Register Bits
inline void clearBit8(char value, char bit){
	value &= ~(1 << bit);
}

inline int _GetVbatt(){
	clearBit8(PRR,PRADC); // Clear Power Reduction ADC bit
	clearBit8(ADMUX, REFS0 | REFS1); //Set Vcc as Vref for ADC (+5VDC)
	clearBit8(ADMUX, MUX0 | MUX1 | MUX2 | MUX3 | MUX4 | MUX5);  //Set PA0 as active analog channel (000000)
	setBit8(ADCSRA, ADPS2); // ADC Prescaler = 16
	clearBit8(ADCSRA, ADPS0 | ADPS1); // ADC Prescaler = 16
	setBit8(ADCSRA, ADEN);  // Enable ADC
	setBit8(ADCSRA, ADATE);  // Enable Auto-Trigger
	setBit8(ADCSRB, ADLAR); // ADC results are RIGHT adjusted
	setBit8(ADCSRA, ADSC);  //Start ADC Conversion
	while bit_is_set(ADCSRA, ADSC){
		//Do Nothing
	}
	int ADC_PA0_Value = (ADCH << 8) | ADCL; // Read ADC register
	Vbatt = (ADC_PA0_Value/1024)*5; // Convert based on Vcc (5V)
	return(Vbatt);
	//clearBit8(ADCSRA, ADEN); // Disables ADC
}

ISR(TIM0_COMPA_vect)
{
	myTimeMs = myTimeMs + 1;
}

void __delay_ms(int delayms){
	int delayTimeMs = delayms + myTimeMs; // Add delay offset to current time
	
	while(delayTimeMs > myTimeMs); // Loop while until Delay Time = current time
	};

int main(void) {
/*
 * Pin Configuration
 * -----------------
 * PA0 -- Input / ADC0 (V_Battery) **Analog Input**
 * PA1 -- Output / (Charge_ElectrodeA)
 * PA2 -- Output / (Charge_ElectrodeB)
 * PA3 -- Output / (Ready_H2O)
 * PA4 -- Output / (LED_1_EN)
 * PA5 -- Output / (LED_2_EN)
 * PA6 -- Output / (LED_3_EN)
 * PA7 -- Output / (Motor_EN)
 * PB0 -- Input / (PowerIn_ElecA) 
 * PB1 -- Input / (PowerIn_ElecB)
 * PB2 -- Input / (In_Water) **Pull-up Resistor Needed** 
 * PB3 -- Output / (RESET) **Triggers LED Gnd**
 */ 
	
	// Set I/O configuration
	DDRA = 0b11111110;	// PA0 = Input, PA1 - PA7 = Output
	PORTA = (0b00000000);  // Disable all Outputs, PA0 pull-up resistor NOT enabled
	DDRB = 0b1000;	// all Port B pins configured as inputs
	PORTB = (0b0111); // enable pull-up resistors on PB0 - PB2

	// Configure System Timer 0 (8 bit timer)
	sei();  // Global Interrupt Enable
	OCR0A = 124;  // Output Compare Register A (set to 124 for 1ms timer with 2MHz Clk)
	TCCR0A |= (1 << WGM01);
	setBit8(TCCR0A,WGM01);  //  Set Clear Timer on Compare (CTC) Match for Waveform Generation Mode
	setBit8(TCCR0A,CS01);  //  Set Clock Select to CLK/8 (2MHz / 8 = 250kHz)
	setBit8(TIMSK0,OCIE0A);  //  Timer/Counter Overflow Interrupt Enable  
	
	while(1){
	
		if (bit_is_clear(PINB, PB2) && motorRunning == false){  // If pushbutton (PB2) is turned on & the motor is not already on
			PORTA |= (1 << PA7); //Turn on the motor (PA7)
			motorRunning = true;
			displayLEDs = true;
		}
		else{
			// do nothing
		}
	
		if (bit_is_set(PINB, PB2)){  //If pushbutton is turned off, turn off the motor (PA7)
				PORTA &= ~(1 << PA7);
				motorRunning = false;
				_GetVbatt();
		}
		else{
			//do nothing
		}
	
		if(motorRunning == true){
			if(displayLEDs == true){
				PORTA |= (1 << PA4);
				_delay_ms(200);
				PORTA |= (1 << PA5);
				_delay_ms(200);
				PORTA |= (1 << PA6);
				_delay_ms(200);
				displayLEDs = false;
			}
		}
		else{
			if(Vbatt > 1){
				PORTA &= ~(1 << PA4); // Turn off LEDs if Vbatt is read and > 0 Volts
				PORTA &= ~(1 << PA5);
				PORTA &= ~(1 << PA6);
			}
		}
		
	}  // end of while(1)
	return(0);
}